/***************************************************************************
 *   mgpi_roeskva.h - Roeskva Graphic Engine Definition Header File        *
 *   Copyright (C) 2008 by cmaster.matso (Maciej Kadłubowski)              *
 *   cmaster.matso@gmail.com                                               *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#ifndef _ROESKVA_H
#define _ROESKVA_H

#ifdef __cplusplus
extern "C" {
#endif

#include "mgpi_g3dmdl.h"

#define MGPI_RENDERBUFFER  10020                                                /** renderbuffer mode */
#define MGPI_MODEL_SMD  10021                                                   /** SMD model loading ID/rendering option */
#define MGPI_MODEL_MD5  10022                                                   /** MD5 model loading ID/rendering option */
#define MGPI_MODEL_OBJ  10023                                                   /** OBJ model loading ID/rendering option */
#define MGPI_SCREEN_QUAD   10024												/** screen aligned quad ID/rendering option */
#define MGPI_SKYBOX_CUBEMAP   10025												/** skybox loading ID/rendering option (cube mapping) */
#define MGPI_POINT_PARTICLE_ARRAY 10026                                         /** color points particles rendering option */
#define MGPI_BILBOARD   10027                                                   /** bliboard loading ID/rendering option */
#define MGPI_SKYBOX 10028                                                       /** skybox loading ID/rendering option */
#define MGPI_SPRITE 10029                                                       /** sprite loading ID/rendering option */
#define MGPI_HEIGHTMAP  10030                                                   /** heightmap loading ID/rendering option */
#define MGPI_BSPMAP 10031                                                       /** BSP map loading ID/rendering option */
/*#define MGPI_RESOLUTION    10032*/
#define MGPI_USER_DEFINED   10032                                               /** user defined rendering option */
#define MGPI_TEXTURE   10033                                                    /** texturing property ID */
#define MGPI_MULTITEXTURE   10034                                               /** multitexturing property ID */
#define MGPI_DISPLAY_CONTEXT    10035                                           /** SDL display context property ID */
#define MGPI_LIGHTS 10036                                                       /** GL lighting property ID */
#define MGPI_GL_ON   10037                                                      /** GL command ON mode */
#define MGPI_GL_OFF  10038                                                      /** GL command OFF mode */
#define MGPI_LIGHT_POSITION 10039                                               /** GL light position property ID */
#define MGPI_LIGHT_DIRECTION    10040                                           /** GL light direction property ID */
#define MGPI_LIGHT_EXPONENT 10041                                               /** GL light exponent property ID */
#define MGPI_LIGHT_CUTOFF   10042                                               /** GL light cut-off property ID */
#define MGPI_LIGHT_AMBIENT  10043                                               /** GL light ambient color property ID */
#define MGPI_LIGHT_SPECULAR 10044                                               /** GL light specular color property ID */
#define MGPI_LIGHT_DIFFUSE  10045                                               /** GL light diffuse color property ID */
#define MGPI_MATERIAL_AMBIENT   10046                                           /** GL material ambient color property ID */
#define MGPI_MATERIAL_DIFFUSE   10047                                           /** GL material diffuse property ID */
#define MGPI_MATERIAL_SPECULAR  10048                                           /** GL material specular color property ID */
#define MGPI_MATERIAL_AMBIENT_DIFFUSE   10049                                   /** GL material ambient and diffuse color property ID */
#define MGPI_MATERIAL_EMISSION  10050                                           /** GL material emission color property ID */
#define MGPI_MATERIAL_SHININESS 10051                                           /** GL material shininess property ID */
#define MGPI_TRANSLATION    10052                                               /** translation mode */
#define MGPI_ROTATION   10053                                                   /** rotation mode */
#define MGPI_SCALING    10054                                                   /** scaling mode */
#define MGPI_SHADERS    10055                                                   /** shaders ON/OFF property ID */
#define MGPI_SHADER_PROGRAM 10059                                               /** shaders program property ID */
#define MGPI_OBJECT_EFFECT  10060                                               /** shaders effect (composition) property ID */
#define MGPI_CLEAR_FLAGS    10061                                               /** GL clear flags property ID */
#define MGPI_ANIM_START 10062                                                   /** animation start property ID */
#define MGPI_ANIM_STOP  10063                                                   /** animation stop property ID */
#define MGPI_TOGGLE_FULL_SCREEN 10064                                           /** fullscreen ON/OFF switch ID */
#define MGPI_SCREEN_BITS    10065                                               /** SDL display context screen bits property ID  */
#define MGPI_PASSES 10066                                                       /** number of passes in composition property ID */
#define MGPI_TRANSFORMATIONS   10067                                            /** objects transformations property ID */
#define MGPI_GL_COMMANDS   10068                                                /** GL commands property ID */
#define MGPI_COLOR  10069                                                       /** color property ID */
#define MGPI_FRAMEBUFFER    10070                                               /** framebuffer mode */
#define MGPI_LIGHT_ATTENUATION  10071                                           /** GL light attenuation property ID */
#define MGPI_GL_CMD_EMPTY   10072                                               /** ID for no GL command used */
#define MGPI_GL_CMD_TEXTURE 10073                                               /** ID of texturing GL command */
#define MGPI_GL_CMD_MULT_2X_BLEND   10074                                       /** ID of dual multiplicative blending GL command */
#define MGPI_GL_CMD_ALPHA_BLEND 10075                                           /** ID of alpha blending GL command */
#define MGPI_GL_CMD_ADD_BLEND   10076                                           /** ID of additive blending GL command */
#define MGPI_GL_CMD_MULT_BLEND  10077                                           /** ID of multiplicative blending GL command */
#define MGPI_GL_CMD_USER    10078                                               /** ID of user defined GL command */
#define MGPI_GL_CMD_COMBINED    10079                                           /** combination of GL commands mode */
#define MGPI_GL_CMD_SHADERS 10080                                               /** ID of shaders GL command */
#define MGPI_GL_CMD_FRAMEBUFFER 10081                                           /** ID of framebuffer usage GL command */
#define MGPI_GL_CMD_RENDER_2D   10082                                           /** ID of rendering in 2D space GL command */
#define MGPI_GL_CMD_MULTITEXTURE    10083                                       /** ID of multitexturing GL command */
#define MGPI_GL_CMD_FOG_LINEAR  10084                                           /** (?) */
#define MGPI_GL_CMD_FOG_EXP 10085                                               /** (?) */
#define MGPI_GL_CMD_FOG_EXP2    10086                                           /** (?) */
#define MGPI_GL_CMD_LIGHTING    10087											/** (?) */
#define MGPI_GL_CMD_MATERIAL    10088											/** (?) */
#define MGPI_MODELVIEW_MATRIX   10089                                           /** model-view matrix injection property ID */
#define MGPI_PROJECTION_MATRIX  10090                                           /** projection matrix injection property ID */
#define MGPI_UNIFORM_LOCATION	10091											/** uniform GLSL variable location property ID */
#define MGPI_UNIFORM_VALUE	10092												/** uniform GLSL variable value property ID */
#define MGPI_VERTEX_ATTRIBUTE_ARRAY	10093										/** veretx attribute array property ID */
#define MGPI_DEPTH	10094														/** depth format ID */
#define MGPI_STENCIL	10095													/** stencil format ID */
#define MGPI_FRAMEBUFFER_MULTISAMPLE	10096									/** (?) */
#define MGPI_MULTISAMPLE	10097												/** (?) */
#define MGPI_POSTPROCESS	10098												/** (?) */
#define MGPI_PREPROCESS		10099												/** (?) */
#define MGPI_SCREEN_QUAD_MULTIPASS	10100										/** (?) */
#define MGPI_SINGLE_PASS_PROCESS	MGPI_PREPROCESS								/** (?) */
#define MGPI_MULTI_PASS_PROCESS		MGPI_POSTPROCESS							/** (?) */

#define MGPI_VERTEX_SHADER	GL_VERTEX_SHADER									/** (?) */
#ifdef GL_ARB_tessellation_shader
#define MGPI_TESS_CONTROL_SHADER	GL_TESS_CONTROL_SHADER						/** (?) */
#define MGPI_TESS_EVALUATION_SHADER	GL_TESS_EVALUATION_SHADER					/** (?) */
#endif
#ifdef GL_VERSION_3_2
#define MGPI_GEOMETRY_SHADER	GL_GEOMETRY_SHADER								/** (?) */
#endif
#define MGPI_FRAGMENT_SHADER	GL_FRAGMENT_SHADER								/** (?) */

#define MGPI_SETUP_DEFAULT  10100                                               /** default engine setup mode */
#define MGPI_SETUP_USER 10101                                                   /** user defined engine setup mode */
#define MGPI_SETUP_BUFFERS  10102                                               /** engine setup mode for buffers (framebuffer) */
#define MGPI_GLSL_UNIFORM    10103                                              /** GLSL uniform variable class ID */
#define MGPI_GLSL_ATTRIBUTE  10104                                              /** GLSL attribute variable class ID */
#define MGPI_GLSL_ATTRIBUTE_ARRAY   10105
#define MGPI_DEFAULT    10106                                                   /** default mode */
#define MGPI_SPRITE_PARTICLE_ARRAY   10107                                      /** sprites array particles mode */
#define MGPI_BILBOARD_PARTICLE_ARRAY    10108                                   /** bilboards array particles mode */
#define MGPI_FOG_PARAMETER  10109                                               /** fog parameter property ID (?) */
#define MGPI_VECTOR 10110                                                       /** vector (max 4 floats/ints) variable mode */
#define MGPI_VALUE  10111                                                       /** single float/int variable mode */
#define MGPI_LIST_MODE    10112                                                 /** list rendering mode */
#define MGPI_ARRAY_MODE 10113                                                   /** array rendering mode */
#define MGPI_RENDER_TARGET  10114                                               /** GL render target property ID */
#define MGPI_VERTEX_SHADER_OBJECT  10115                                        /** vertex shader object property ID */
#define MGPI_GEOMETRY_SHADER_OBJECT 10116                                       /** geometry shader object property ID */
#define MGPI_FRAGMENT_SHADER_OBJECT 10117                                       /** fragment shader object property ID */
#define MGPI_PRECOMPILED_SHADERS    10118                                       /** precompiled shaders mode */

#define MGPI_ENABLE     MGPI_TRUE                                               /** enable ID */
#define MGPI_DISABLE    MGPI_FALSE                                              /** disable ID */
#define MGPI_NO_ANIMATION   -1                                                  /** default index value for no animation */
#define MGPI_MAX_USER_COMMANDS  8                                               /** max number of user defined GL command per combination */
#define MGPI_MAX_RENDERING_SECTIONS 8                                           /** max number of rendering sections */
#define MGPI_MAX_RENDERING_OBJECTS  512                                         /** max number of rendering object */
#define MGPI_MAX_FRAMEBUFFERS   8                                               /** max number of framebuffers */
#define MGPI_DEFAULT_FRAMEBUFFER    0                                           /** default framebuffer index */
#define MGPI_MAX_MATERIALS_PER_PASS 32                                          /** max number of materials per single rendering pass */
#define MGPI_OBJECT	0															/** object program selector ID */
#define MGPI_MAX_UNIFORM_VARIABLES	32											/** max number of user-defined uniform variables */
#define MGPI_MAX_VERTEX_ATTRIBUTE_ARRAYS	32									/** max number of user-defined vertex attributs arrays */
#define MGPI_MAX_PASSES_PER_EFFECT	32											/** max number of passes per effect */
#define MGPI_MAX_UNIFORMS_PER_PASS	48											/** (?) */
#define MGPI_MULTIPASS_PROCESS_TEXTURES	3										/** (?) */

    typedef int pname_t;                                                        /** property name */
    typedef int glsl_t;                                                         /** GLSL variable type */
    typedef int engs_t;                                                         /** engine setup ID */
    typedef int glcmds_t;                                                       /** GL command ID */
    typedef int rendobj_t;                                                      /** rendering object ID */
    typedef int glsl_class_t;                                                   /** GLSL variable class */

#pragma pack(push,1)

    typedef struct _clrpart {
        float4 *vertex_array;                                                   /** particles positions */
        float4 *color_array;                                                    /** particles colors */
        float4 *normal_array;                                                   /** normals in the points */
        unsigned int *index_array;                                              /** indices array for the particles */
        int num_parts;                                                          /** number of the particles */
        int num_indices;                                                        /** number of indices */
    } clrpart_t;                                                                /** color point particles */

	typedef struct {
		int num_passes;															/** number of passes in the effect */
		GLuint passes[MGPI_MAX_PASSES_PER_EFFECT];								/** passes data array */
		GLuint locations[MGPI_MAX_PASSES_PER_EFFECT]
				[MGPI_MAX_UNIFORMS_PER_PASS+MGPI_MULTIPASS_PROCESS_TEXTURES];	/** user-defiend textures and other uniforms locations */
		void *refs[MGPI_MAX_UNIFORMS_PER_PASS];									/** references to user-defined uniforms' variables (?) */
	} effect_t;																	/** effect control object */

    struct _multitex {                                                          /** multitexturing control object */
        int tex_name;                                                           /** GL texture name */
        int tex_targ;                                                           /** GL texture target */
        int num;                                                                /** number of textures in the multitexturing array */
        char *param_name;                                                       /** incode shader sampler parameter name */
		GLuint location;														/** shader texture loaction */
    };

    struct _shaders {                                                           /** shaders control object */
        int num;                                                                /** number of shaders in array */
        GLuint *shaders, program_id;                                            /** shaders GL names and their program ID */
        GLuint shaders_programs[3];                                             /** array of shader programs for precompiled shaders */
    };

    struct _fbuffer {                                                           /** framebuffer control object */
        int index;                                                              /** index of framebuffer selected for usage????? */
        GLuint used_id;                                                         /** GL name of the used framebuffer */
        GLuint output;                                                          /** GL name of the attached texture */
        GLuint target;                                                          /** target of the attached texture */
        GLuint attachment;                                                      /** attachment type */
		GLuint depth;															/** depth renderbuffer */
		GLuint stencil;															/** stencil renderbuffer */
		GLuint slice;															/** texture 3D slice */
		GLuint multisample;														/** GL name of the multisample framebuffer */
		int w, h;																/** sizes of the framebuffer */
    };

    struct _lighting {/* TODO: IMPLEMENT IT */
        GLenum id;
        float4 position;
        float4 direction;
        float cut_off;
        float exponent;
        float4 ambient;
        float4 specular;
        float4 diffuse;
        float4 attenuation;
    };

    struct _material {/* TODO: IMPLEMENT IT */
        float4 ambient;
        float4 specular;
        float4 diffuse;
        float4 ambient_diffuse;
        float4 emission;
        float shininess;
    };

    struct _fog {/* TODO: IMPLEMENT IT */
        float start;
        float end;
        float density;
        float4 color;
    };

	struct _usrcmds {															/** user-defined commands control object */
        int num;																/** number of user-defined commands */
        int free;																/** (?) */
        int current;															/** (?) */
        void (*user_gl_cmd_pre[MGPI_MAX_USER_COMMANDS])(struct _rendnode *);	/** pre-stage user-defined command routines array */
        void (*user_gl_cmd_post[MGPI_MAX_USER_COMMANDS])(struct _rendnode *);	/** post-stage user-defined command routines array */
    };

	struct _unif_var {															/** shaders unifrom variables control object */
        GLuint location;														/** shader variable location */
        int type;																/** variable type */
        float *pointer;															/** pointer to variable data */
        int length;																/** variable data length */
        int n;																	/** number of used variables */
    };

	struct _vert_attr {															/** shaders vertex attributes control object */
		int number;																/** number of vertex attributes */
		const char *name;														/** (?) */
		GLuint index;															/** (?) */
		GLint size;																/** vertex attribute data size */
		GLenum type;															/** vertex attribute data type */
		GLboolean normalized;													/** normalized data indication flag */
		GLsizei stride;															/** vertex attribute data stride */
		const GLvoid *pointer;													/** vertex attribute data pointer */
	};

	struct _void_ptr {
		int size;
		void *ptr;
	};

    MGPI_API typedef struct _rendnode {
        struct _rendnode *next;
        struct _rendnode *prev;
        
        int type;																/** rendering entity (node) type */
        int elem_id;															/** rendering entity (node) ID */
        int tex_id;																/** default, single texture ID */
        int tex_targ;															/** default, single texture target */
        int flag;																/** auxiliary rendering entity flag */

        void *rd_ptr;															/** generic rendering data pointer */
        void *an_ptr;															/** generic animation data pointer */

        void (*gl_transformations)(struct _rendnode *);							/** user-defined entity transformation routine */
        
        int number_of_cmds;														/** number of entity effect commands */
        int *combined_cmds_array;												/** effect commands flags pointer */

        void (*gl_commands_pre)(struct _rendnode *);							/** pre-stage effect command/s */
        void (*gl_commands_post)(struct _rendnode *);							/** post-stage effect command/s */

        struct _shaders shaders;												/** entity rendering effect shaders data */
        struct _fbuffer fbuffer;												/** entity framebuffer data */
        struct _usrcmds usrcmds;												/** user-defined effect commands data */
        struct _unif_var gl_var[MGPI_MAX_UNIFORM_VARIABLES];					/** shaders' uniform variables information */
		struct _vert_attr gl_vert_attribs[MGPI_MAX_VERTEX_ATTRIBUTE_ARRAYS];	/** shaders' vertex attributes information */
        struct _multitex *mt_ptr;												/** multi-texturing data pointer */
        
    } rendnode_t;
	MGPI_API typedef rendnode_t rentity_t;										/** rendering entity type definition */

    MGPI_API typedef struct _roeskva {
        int hcamera;
		int handles[32];
		float *pointer;

        int (*setup)(engs_t, ...);												/** Sets-up engine with given configuration option */

        int (*loadObject)(const char *, rendobj_t);								/** Loads rendering entity of given type */
        int (*loadAnimation)(int, const char *);								/** Loads rendering entity animation data */
        int (*renderObject)(int);												/** Draws given rendering entity to bound framebuffer */
        void (*renderObjectAsync)(int);											/** (?) */
        int (*releaseObject)(int);												/** Releases rendering entity data (!IMPLEMENT!) */

        int (*createCamera)(pname_t);											/** Creates engine camera of given type. */
        int (*updateCamera)(int);												/** Updates state of the given camera */
        void (*commitChanges)(void);											/** Commits changes to bound framebuffer */

		void (*update)(struct _void_ptr *);										/** Updates thread data with one from the front dispatch buffer */
		void (*commit)(struct _void_ptr *);										/** Commits data to back dispatch buffer */

        int (*genList)(void);													/** DEPRECATED */
        int (*renderList)(int);													/** DEPRECATED */
        int (*delList)(int);													/** DEPRECATED */

        GLuint (*setupShader)(pname_t, int, const char **, const int *);		/** Creates engine shader object */
        int (*setVariable)(glsl_t, glsl_class_t, const char *, ...);			/** DEPRECATED */

        GLuint (*setupProgram)(GLuint *, int);									/** Creates engine program object */
        void (*selectProgram)(int);												/** Selects engine program object of given ID for usage */

        int (*selectObject)(int);												/** Selects rendering entity of given ID for usage */
        int (*getProperty)(pname_t, ...);										/** Engine property getter */
        int (*setProperty)(pname_t, ...);										/** Engine property setter */

        int (*setObjectTransformations)(int, void (*)(rendnode_t *));			/** DEPRECATED */
        int (*setObjectGLCommands)(int, glcmds_t, ...);							/** DEPRECATED */

		int (*loadObjectComposition)(const char *, rendobj_t, int);				/** DEPRECATED */
        int (*releaseObjectComposition)(int, int);								/** DEPRECATED */
        int (*renderObjectComposition)(int, int);								/** DEPRECATED */
        void (*renderObjectCompositionAsync)(int, int);							/** DEPRECATED */

        void (*renderString)(float3, float3, void *, char *);					/** Draws string to bound framebuffer */
        void (*renderDiagnostic)(void);											/** Draws diagnostic informations to bound framebuffer */
        void (*waitFrame)(int);													/** Synchronizes frame */

        /* NEW */
        //int (*addPass)(void);
        //int (*addMaterial)(GLuint, GLuint, GLuint, void (*)(struct _rendnode *));/*!!!user-defined commands!!!*/
        //void (*selectPass)(int);
        //void (*addMaterialToPass)(int);

        //void (*render)(void);
        /* ... */
    } Roeskva_t;

#ifndef WIN32
    typedef int HANDLE;
#endif

#pragma pack(pop)

    /**
     * Implements the Roeskva interface.
     */
    int MGPI_API engImplement(Roeskva_t *engine);

    /**
     * Starts the Roeskva engine.
     */
    int MGPI_API engStart(Roeskva_t *engine);

    /**
     * Stops the Roeskva engine.
     */
    int MGPI_API engStop(Roeskva_t *engine);

    /* TODO: do it in different way... V */
    void /*MGPI_API*/ *engGetRenderingObject(int id);
    rendnode_t /*MGPI_API*/ *engGetRenderingNode(int id);

    extern int e_renderExtDefined(rendnode_t *node);

#ifdef __cplusplus
}
#endif

#endif
